package userAdmin

import (
	"bufio"
	"crypto/rand"
	"encoding/base64"
	"fmt"
	"io/ioutil"
	"mysqlAdmin/lib/log"
	"os"
	"os/exec"
	"strings"
)

const (
	userFile string = "/etc/passwd"
)

type Users struct {
	Users []User `json:"users"`
}

type User struct {
	Name      string `json:"name"`
	Directory string `json:"directory"`
	Group     string `json:"group"`
	Shell     string `json:"shell"`
}

// Read json file and return slice of byte.
func ReadUsers(f string) []byte {

	jsonFile, err := os.Open(f)

	if err != nil {
		fmt.Println(err)
	}
	defer jsonFile.Close()

	data, _ := ioutil.ReadAll(jsonFile)
	return data
}

// Read file /etc/passwd and return slice of users
func ReadEtcPasswd(f string) (list []string) {

	file, err := os.Open(f)
	if err != nil {
		panic(err)
	}
	defer file.Close()

	r := bufio.NewScanner(file)

	for r.Scan() {
		lines := r.Text()
		parts := strings.Split(lines, ":")
		list = append(list, parts[0])
	}
	return list
}

// Return securely generated random bytes
func CreateRandom(n int) string {
	b := make([]byte, n)
	_, err := rand.Read(b)
	if err != nil {
		fmt.Println(err)
	}
	return string(b)
}

// User is created by executing shell command useradd
func AddNewUser(u *User) (bool, string) {

	encrypt := base64.StdEncoding.EncodeToString([]byte(CreateRandom(9)))
	addGroup()
	argUser := []string{"-m", "-u", "27", "-d", u.Directory, "-g", "mysql", "-s", u.Shell, u.Name}
	argPass := []string{"-c", fmt.Sprintf("echo %s:%s | chpasswd", u.Name, encrypt)}

	userCmd := exec.Command("/usr/sbin/useradd", argUser...)
	passCmd := exec.Command("/bin/sh", argPass...)

	if out, err := userCmd.Output(); err != nil {
		log.Errorf("创建mysql用户失败,异常信息:%v", err)
		return false, ""
	} else {

		log.Infof("创建用户命令输出: %s\n", out)

		if _, err := passCmd.Output(); err != nil {
			log.Errorf("创建mysql用户失败,异常信息:%v", err)
			return false, ""
		}
		return true, encrypt
	}
}

func addGroup() {
	delCmd := exec.Command("/usr/sbin/groupadd", "-g", "27", "mysql")
	if out, err := delCmd.Output(); err != nil {
		log.Errorf("删除用户失败,out:%v,err:%v ", out, err)
	}
}

func DelMySQL() {
	delCmd := exec.Command("/usr/sbin/userdel", "mysql")
	if out, err := delCmd.Output(); err != nil {
		log.Errorf("删除用户失败,out:%v,err:%v ", out, err)
	}
}

func ChceckUserExists(userName string) bool {

	userList := ReadEtcPasswd(userFile)
	for _, user := range userList {
		if userName == user {
			return true
		}
	}

	return false
}

func Add() {

	user := User{Name: "mysql", Directory: "/usr/local/mysql", Shell: "/bin/false", Group: "mysql"}

	// 检查用户是否存在
	if ChceckUserExists(user.Name) {
		return
	}

	flag, passwd := AddNewUser(&user)
	if !flag {
		log.Error("mysql用户已经存在")
		return
	}
	log.Infof("创建用户成功，口令:%s", passwd)

}

func Del() {
	user := User{Name: "mysql", Directory: "/usr/local/mysql", Shell: "/bin/false", Group: "mysql"}

	// 检查用户是否存在
	if !ChceckUserExists(user.Name) {
		return
	}

	DelMySQL()
}
